package roborally.Pieces;
import be.kuleuven.cs.som.annotate.*;

/**
 * This is a class representing a Game Piece. Since the position can also be a PositionWithOrientation, the only characteristic ascribed to 
 * this class is whether the object is terminated.
 * @invar 	The bidirectional association between Board and this GamePiece with respect to Positions is consistent.
 * 			| if this.getPosition() != null then 
 * 			|	let board = this.getPosition().getBoard() in
 * 			|		board.getItemsAt(this.getPosition()).contains(this) || board.getRobotAt(this.getPosition() ).equals(this) ||
 * 			|		board.getWallAt(this.getPosition() ).equals(this)
 * 			|	and !exists Position position with 
 *			|		!position.equals(this.getPosition() ) && (position.getBoard().getItemsAt(position).
 *			|		contains(this) || position.getBoard().getRobotAt(position).equals(this) ||
 * 			|		position.getBoard().getWallAt(position).equals(this)
 * 
 * @version 3.0
 * @author Bart Opsomer 2de Bachelor Ingenieurswetenschappen Electrotechniek-Computerwetenschappen 
 * 		   Peter Opsomer 1ste Master Wiskundige IngenieursTechnieken
 */
public abstract class GamePiece {

	private boolean terminated;
	/**
	 * Creates a Gamepiece which is not located at any position on any Board: use method setPosition 
	 * or setPositionWithOrientation for this.
	 * 
	 * @post | !new.isTerminated()
	 */
	@Raw @Model
	protected GamePiece() {
		this.terminated = false;
	}
	/**
	 * @return true if this GamePiece is terminated and ready for garbage-collection
	 */
	@Basic
	public boolean isTerminated() {
		return this.terminated;
	}
	/**
	 * Terminate this GamePiece and make it ready for garbage-collection. This method should be overridden by all subclasses 
	 * because no Board can contain terminated GamePieces.
	 * 
	 * @post | new.isTerminated()
	 */
	public void terminate() {
		this.terminated = true;
	}
	/**
	 * @return the Position of this GamePiece on a Board
	 */
	public abstract Position getPosition();
	/**
	 * Return a String to be added to the toString()-methods of subclasses. This method is not abstract, but subclasses should overwrite this
	 * method to get a representative name for them in the GUI. This method just gives info about the position of the GamePiece.
	 * 
	 * @return | if getPosition() == null) then 
	 * 		   |	result.endsWith(" not located on any Board")
	 * 		   | else 
	 * 		   |	result.endsWith(" at position (" + getPosition().getX() + "," + getPosition().getY() + ")")
	 */
	public String toString(){
		if(getPosition() == null)
			return " not located on any Board";
		return " at position (" + getPosition().getX() + "," + getPosition().getY() + ")";
	}
	/**
	 * The method that executes the effect of a robot shooting this GamePiece, to be overriden by the subclasses.
	 */
	public abstract void shootThis();
}
